package com.spark.util;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.spark.core.CacheManager;
import com.spark.core.SparkConfiguration;

public class SourceFileScanner {
	private static SourceFileScanner instance;
	private SparkConfiguration configuration;
	private Map<String, Long> lastModifiedCache = new HashMap<String, Long>(100);
	private FileCheckThread checkThread = new FileCheckThread("SourceFileScanner.FileCheckThread");
	private List<String> updates = new ArrayList<String>();
	
	private long checkInterval = 5000;

	private boolean isStarted = false;

	public static void init(SparkConfiguration configuration) {
		instance = new SourceFileScanner(configuration);
	}

	public static SourceFileScanner getInstance() {
		return instance;
	}

	private SourceFileScanner(SparkConfiguration configuration) {
		this.configuration = configuration;
	}
	
	private void updateCache(){
		if(updates.size() > 0) {
			CacheManager.getInstance().clearCache(updates);
//			System.out.println("Update Screens: " + updates.size());
			updates.clear();
		}
	}
	

	public boolean startUp() {
		if (isStarted) return true;
		isStarted = true;
		checkThread.start();
		return true;
	}

	public void shutDown() {
		isStarted = false;
		checkThread.interrupt();
	}
	
	private void scanScreen(File file){
		if(file == null) file = new File(configuration.getContextPath());
		if(file.exists()){
			if(file.isDirectory()){
				File[] files = file.listFiles();
				for(int i=0;i<files.length;i++){
					scanScreen(files[i]);
				}
			}else {
				String name = file.getName();
				if(name != null && name.indexOf(".screen") != -1){
					String path = file.getAbsolutePath();
					long fileLastModified = file.lastModified();
					Long lastModified = lastModifiedCache.get(path);
					if(lastModified == null || fileLastModified != lastModified){
						updates.add(path);
						lastModifiedCache.put(path, new Long(fileLastModified));
					}
				}
			}
		}
	}

	public class FileCheckThread extends Thread {

		public FileCheckThread(String name) {
			super(name);
		}

		public void run() {
			while (isStarted) {
				scanScreen(new File(configuration.getContextPath()));
				updateCache();
				try {
					sleep(checkInterval);
				} catch (InterruptedException ex) {
					return;
				}
			}

		}

	};

}
